<?php

namespace App\Common\Lib;

use App\Common as com;
use App\Common\Lib\StaticPool as nameStaticPool;

/**
 * 单例池
 * @package App\Common\Lib
 */
class StaticPool extends com\Lib\LibBase {

	/**
	 * 数组值为true表示正在初始化中
	 * @var array
	 */
	public static array $staticPool = [];

	/**
	 * 获取或创建（如果不存在则创建）
	 * @param string $className 完整类名
	 * @param \Closure $newCallback 创建的回调
	 * @return mixed
	 */
	public static function getOrNew( string $className, \Closure $newCallback ):mixed {
		if( ! self::has( $className ) ){
			// 先占位，表示正在初始化中
			self::$staticPool[ $className ] = true;
			//
			self::$staticPool[ $className ] = $newCallback();
		}
		//
		if( self::$staticPool[ $className ] === true ){
			// 等待1毫秒
			\Swoole\Coroutine::sleep( 0.001 );
			// 重新获取
			return self::getOrNew( $className, $newCallback );
		}
		//
		return self::$staticPool[ $className ];
	}

	/**
	 * 获取或创建（如果不存在则创建）
	 * @param string $className 完整类名
	 * @param int|string|array $paramsMixed 池参数
	 * @param \Closure $newCallback 创建的回调
	 * @return mixed
	 */
	public static function getOrParams( string $className, int|string|array $paramsMixed, \Closure $newCallback ):mixed {
		$paramsMixedStr = is_array( $paramsMixed ) ? implode( '_', $paramsMixed ) : $paramsMixed;
		return self::getOrNew( "{$className}=>{$paramsMixedStr}", $newCallback );
	}

	/**
	 * 删除
	 * @param string $className
	 * @return bool
	 */
	public static function del( string $className ):bool {
		unset( self::$staticPool[ $className ] );
		//
		return true;
	}

	/**
	 * 是否存在
	 * @param string $className
	 * @return bool
	 */
	public static function has( string $className ):bool {
		return isset( self::$staticPool[ $className ] );
	}

}
